package com.zt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zt.aliyun.AliMessage;
import com.zt.constant.SystemConstants;
import com.zt.dto.LoginRequest;
import com.zt.dto.UpdatePasswordRequest;
import com.zt.entity.Result;
import com.zt.jwt.JwtUtils;
import com.zt.pojo.Banners;
import com.zt.pojo.Coupons;
import com.zt.pojo.Users;
import com.zt.service.CouponsService;
import com.zt.service.UsersService;
import com.zt.mapper.UsersMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.PhoneUtil;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.CompletableFuture;
import java.util.regex.Pattern;
import com.zt.enums.MembershipType;
import lombok.extern.slf4j.Slf4j;

/**
* @author 洪
* @description 针对表【users(用户基础信息表)】的数据库操作Service实现
* @createDate 2025-04-10 09:58:53
*/
@Service
@Slf4j
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users>
    implements UsersService{
    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private CouponsService couponsService;
    @Autowired
    private RedisTemplate<String, String> couponRedisTemplate;
    
    // 验证码的Redis前缀
    private static final String CODE_KEY_PREFIX = "login:code:";
    // 验证码过期时间（分钟）
    private static final Long CODE_TTL = 5L;
    // 密码加密盐值
    private static final String PASSWORD_SALT = "tutoruser";

    // 刷新Token的Redis前缀
    private static final String REFRESH_TOKEN_KEY_PREFIX = "login:refresh_token:";
    // accessToken过期时间（毫秒）
    private static final long ACCESS_TOKEN_EXPIRE = 2 * 60 * 60 * 1000L; // 2小时
    // refreshToken过期时间（毫秒）
    private static final long REFRESH_TOKEN_EXPIRE = 7 * 24 * 60 * 60 * 1000L; // 7天
    // refreshToken在Redis中的过期时间（天）
    private static final long REFRESH_TOKEN_REDIS_TTL = 7;

    // 优惠券的Redis前缀
    private static final String COUPONS_KEY = "coupons:";
    // 新用户优惠券过期时间（天）
    private static final long NEW_USER_COUPON_TTL = 7;
    // 新用户默认优惠券ID
    private static final Integer DEFAULT_COUPON_ID = 1;
    
    // 手机号验证正则表达式（11位数字）
    private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");

    /**
     * 验证手机号格式
     * @param phone 手机号
     * @return 验证结果
     */
    private boolean validatePhoneFormat(String phone) {
        return phone != null && PHONE_PATTERN.matcher(phone).matches();
    }

    @Override
    public Result getCode(String phone) {
        // 1. 参数校验
        if (StrUtil.isBlank(phone)) {
            return Result.error("手机号不能为空");
        }
        
        // 验证手机号是否为11位
        if (!validatePhoneFormat(phone)) {
            return Result.error("手机号格式不正确，请输入11位有效手机号");
        }
        
        // 2. 生成6位随机验证码
        String code = RandomUtil.randomNumbers(6);
        
        // 3. 将验证码存入Redis，设置过期时间为5分钟
        redisTemplate.opsForValue().set(CODE_KEY_PREFIX + phone, code, CODE_TTL, TimeUnit.MINUTES);
        
        // 4. 实际项目中这里需要调用短信服务发送验证码，此处省略
        AliMessage aliMessage = new AliMessage();
        String message = aliMessage.alicode(code,phone);
        System.out.println("发送验证码结果"+message);

        return Result.success("验证码发送成功"); // 真实环境中不应返回验证码，这里为了测试方便
    }

    @Override
    public Result login(LoginRequest loginRequest) {
        if (loginRequest == null) {
            return Result.error("登录请求不能为空");
        }

        String loginType = loginRequest.getLoginType();

        // 根据登录类型选择不同的登录方式
        if ("password".equals(loginType)) {
            return passwordLogin(loginRequest);
        } else {
            // 验证码 登录
            return codeLogin(loginRequest);
        }
    }

    /**
     * 密码登录
     */
    private Result passwordLogin(LoginRequest loginRequest) {
        String account = loginRequest.getAccount();
        String password = loginRequest.getPassword();

        // 1. 参数校验
        if (StrUtil.isBlank(account)) {
            return Result.error("账号不能为空");
        }
        if (StrUtil.isBlank(password)) {
            return Result.error("密码不能为空");
        }

        // 2. 查询用户（这里假设account就是手机号）
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getPhone, account);
        Users user = this.getOne(queryWrapper);

        if (user == null) {
            return Result.error("用户不存在");
        }

        // 3. 验证密码
        if (StrUtil.isBlank(user.getPassword())) {
            return Result.error("该用户未设置密码，请使用验证码登录");
        }

        // 使用MD5加密验证密码
        String encryptedPassword = DigestUtils.md5DigestAsHex((password + PASSWORD_SALT).getBytes());
        if (!encryptedPassword.equals(user.getPassword())) {
            return Result.error("密码错误");
        }

        // 4. 生成并存储Token
        Map<String, Object> tokenMap = generateAndStoreTokens(user.getId().toString());
        tokenMap.put("user", user);

        return Result.success("登录成功", tokenMap);
    }

    /**
     * 验证码登录
     */
    private Result codeLogin(LoginRequest loginRequest) {
        String phone = loginRequest.getPhone();
        String code = loginRequest.getCode();

        // 1. 参数校验
        Result validationResult = validateLoginParams(phone, code);
        if (validationResult != null) {
            return validationResult;
        }

        // 2. 验证码校验
        Result codeValidationResult = validateVerificationCode(phone, code);
        if (codeValidationResult != null) {
            return codeValidationResult;
        }

        // 3. 查询或创建用户
        Users user = getOrCreateUser(phone);

        // 4. 生成并存储Token
        Map<String, Object> tokenMap = generateAndStoreTokens(user.getId().toString());
        tokenMap.put("user", user);

        return Result.success("登录成功", tokenMap);
    }
    
    /**
     * 验证登录参数是否合法
     * @param phone 手机号
     * @param code 验证码
     * @return 如果参数不合法返回错误结果，否则返回null
     */
    private Result validateLoginParams(String phone, String code) {
        if (StrUtil.isBlank(phone)) {
            return Result.error("手机号不能为空");
        }
        
        if (!validatePhoneFormat(phone)) {
            return Result.error("手机号格式不正确，请输入11位有效手机号");
        }
        
        if (StrUtil.isBlank(code)) {
            return Result.error("验证码不能为空");
        }
        
        return null;
    }
    
    /**
     * 验证验证码是否正确
     * @param phone 手机号
     * @param code 用户输入的验证码
     * @return 如果验证码不正确返回错误结果，否则返回null
     */
    private Result validateVerificationCode(String phone, String code) {
        String cacheCode = redisTemplate.opsForValue().get(CODE_KEY_PREFIX + phone);
        
        if (cacheCode == null) {
            return Result.error("验证码已过期或不存在");
        }
        
        if (!code.equals(cacheCode)) {
            return Result.error("验证码错误");
        }
        
        // 验证通过，删除Redis中的验证码，防止重复使用
        redisTemplate.delete(CODE_KEY_PREFIX + phone);
        
        return null;
    }
    
    /**
     * 获取或创建用户
     * @param phone 手机号
     * @return 用户对象
     */
    private Users getOrCreateUser(String phone) {
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getPhone, phone);
        Users user = this.getOne(queryWrapper);
        
        if (user == null) {
            user = createNewUser(phone);
        }
        
        return user;
    }
    
    /**
     * 创建新用户
     * @param phone 手机号
     * @return 新创建的用户对象
     */
    private Users createNewUser(String phone) {
        Users user = new Users();
        user.setPhone(phone);
        user.setNickname("用户" + phone.substring(phone.length() - 4));
        Date now = new Date();
        user.setCreatedAt(now);
        user.setUpdatedAt(now);
        user.setStatus(SystemConstants.USER_STATUS_NORMAL);
        user.setRole(SystemConstants.ROLE_STUDENT);  // 默认为学生角色

        // 保存用户
        this.save(user);

        // 新用户注册成功后，自动发放优惠券
        giveNewUserCoupon(Long.valueOf(user.getId()));

        return user;
    }

    /**
     * 为新用户发放优惠券
     * @param userId 用户ID
     */
    private void giveNewUserCoupon(Long userId) {
        try {
            // 获取ID为1的优惠券
            Coupons coupon = couponsService.getById(DEFAULT_COUPON_ID);
            if (coupon == null) {
                log.warn("默认优惠券不存在，ID: {}", DEFAULT_COUPON_ID);
                return;
            }

            ObjectMapper mapper = new ObjectMapper();
            List<Coupons> couponsList = new ArrayList<>();
            couponsList.add(coupon);

            // 将优惠券列表存储到Redis，设置7天过期时间
            String couponsKey = COUPONS_KEY + userId;
            String couponsJson = mapper.writeValueAsString(couponsList);
            couponRedisTemplate.opsForValue().set(couponsKey, couponsJson, NEW_USER_COUPON_TTL, TimeUnit.DAYS);

            log.info("新用户 {} 注册成功，已自动发放优惠券，ID: {}", userId, DEFAULT_COUPON_ID);
        } catch (Exception e) {
            log.error("为新用户 {} 发放优惠券失败: {}", userId, e.getMessage(), e);
        }
    }
    
    /**
     * 生成并存储Token
     * @param userId 用户ID
     * @return 包含accessToken和refreshToken的Map
     */
    private Map<String, Object> generateAndStoreTokens(String userId) {
        // 生成accessToken，有效期短
        String accessToken = JwtUtils.generateToken(userId, ACCESS_TOKEN_EXPIRE);
        
        // 生成refreshToken，有效期长
        String refreshToken = JwtUtils.generateToken(userId, REFRESH_TOKEN_EXPIRE);
        
        // 将refreshToken存入Redis，用于后续刷新accessToken验证
        redisTemplate.opsForValue().set(
            REFRESH_TOKEN_KEY_PREFIX + userId, 
            refreshToken, 
            REFRESH_TOKEN_REDIS_TTL, 
            TimeUnit.DAYS
        );
        
        // 构建返回结果
        Map<String, Object> tokenMap = new HashMap<>(2);
        tokenMap.put("accessToken", accessToken);
        tokenMap.put("refreshToken", refreshToken);
        
        return tokenMap;
    }
    
    @Override
    public Result refreshToken(String refreshToken) {
        // 1. 参数校验
        if (StrUtil.isBlank(refreshToken)) {
            return Result.error("刷新Token不能为空");
        }
        
        // 2. 验证refreshToken是否有效
        if (!JwtUtils.validateToken(refreshToken)) {
            return Result.error("刷新Token已过期或无效");
        }
        
        // 3. 从refreshToken中获取用户ID
        String userId = JwtUtils.getUsernameFromToken(refreshToken);
        if (userId == null) {
            return Result.error("刷新Token无效");
        }
        
        // 4. 从Redis中获取保存的refreshToken并验证
        String cacheRefreshToken = redisTemplate.opsForValue().get(REFRESH_TOKEN_KEY_PREFIX + userId);
        if (cacheRefreshToken == null || !cacheRefreshToken.equals(refreshToken)) {
            return Result.error("刷新Token已失效，请重新登录");
        }
        
        // 5. 验证通过，生成新的accessToken
        String newAccessToken = JwtUtils.generateToken(userId, ACCESS_TOKEN_EXPIRE);
        
        // 6. 返回新的accessToken
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put("accessToken", newAccessToken);
        
        return Result.success("Token刷新成功", tokenMap);
    }

    @Override
    public Result getUserInfo(Long id) {
        try {
            // 调用 Mapper 方法获取用户信息
            Users user = usersMapper.ListMy(id);
            if (user != null) {
                return Result.success("获取用户信息成功", user);
            }
            return Result.error("用户不存在");
        } catch (Exception e) {
            log.error("获取用户信息失败", e);
            return Result.error("获取用户信息失败");
        }
    }

    @Override
    public Result getBanner() {
        List<Banners> list=usersMapper.ListBanner();
        return Result.success("获取轮播图成功", list);
    }

    @Override
    @Transactional
    public boolean updateUserMembershipStatus(Long userId, Integer membershipType) {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        
        // 获取会员类型对应的天数
        int days = 0;
        if (membershipType != null) {
            MembershipType type = null;
            try {
                // 将整数值转换为枚举
                type = MembershipType.values()[membershipType];
                days = type.getDays();
            } catch (ArrayIndexOutOfBoundsException e) {
                // 处理无效的会员类型值
                log.error("无效的会员类型: {}", membershipType);
            }
        }
        
        // 计算会员到期时间
        LocalDateTime expirationTime = now.plusDays(days);
        
        LambdaUpdateWrapper<Users> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Users::getId, userId)
                    .set(Users::getHy, membershipType)
                    .set(Users::getHySj, now.format(formatter))
                    .set(Users::getHyDq, expirationTime.format(formatter));
        
        boolean updated = update(updateWrapper);
        
        if (updated) {
            // 异步发送会员开通推送消息
            CompletableFuture.runAsync(() -> {
                try {
                    Users user = getById(userId);
                    if (user != null) {
                        // TODO: 添加会员开通推送逻辑
                        log.info("用户 {} 开通会员成功，级别：{}，有效期至：{}", userId, membershipType, expirationTime.format(formatter));
                    }
                } catch (Exception e) {
                    log.error("发送会员开通推送消息失败: {}", e.getMessage());
                }
            });
        }
        
        return updated;
    }

    /**
     * 使用String类型的userId更新用户会员状态
     * 内部方法，不覆盖接口
     * @param userId 用户ID (字符串类型)
     * @param membershipLevel 会员级别
     * @param days 会员有效期天数
     * @return 是否更新成功
     */
    @Transactional
    public boolean updateUserMembershipStatus(String userId, Integer membershipLevel, int days) {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        
        // 计算会员到期时间
        LocalDateTime expirationTime = now.plusDays(days);
        
        LambdaUpdateWrapper<Users> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Users::getId, userId)
                    .set(Users::getHy, membershipLevel)
                    .set(Users::getHySj, now.format(formatter))
                    .set(Users::getHyDq, expirationTime.format(formatter));
        
        boolean updated = update(updateWrapper);
        
        if (updated) {
            // 异步发送会员开通推送消息
            CompletableFuture.runAsync(() -> {
                try {
                    Users user = getById(userId);
                    if (user != null) {
                        // TODO: 添加会员开通推送逻辑
                        log.info("用户 {} 开通会员成功，级别：{}，有效期至：{}", userId, membershipLevel, expirationTime.format(formatter));
                    }
                } catch (Exception e) {
                    log.error("发送会员开通推送消息失败: {}", e.getMessage());
                }
            });
        }
        
        return updated;
    }
    
    @Override
    @Transactional
    public boolean updateUserMembershipStatus(Long userId, Integer membershipLevel, int days) {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        
        // 计算会员到期时间
        LocalDateTime expirationTime = now.plusDays(days);
        
        LambdaUpdateWrapper<Users> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Users::getId, userId)
                    .set(Users::getHy, membershipLevel)
                    .set(Users::getHySj, now.format(formatter))
                    .set(Users::getHyDq, expirationTime.format(formatter));
        
        boolean updated = update(updateWrapper);
        
        if (updated) {
            // 异步发送会员开通推送消息
            CompletableFuture.runAsync(() -> {
                try {
                    Users user = getById(userId);
                    if (user != null) {
                        // TODO: 添加会员开通推送逻辑
                        log.info("用户 {} 开通会员成功，级别：{}，有效期至：{}", userId, membershipLevel, expirationTime.format(formatter));
                    }
                } catch (Exception e) {
                    log.error("发送会员开通推送消息失败: {}", e.getMessage());
                }
            });
        }
        
        return updated;
    }

    /**
     * 修改用户角色
     * @param userId 用户ID
     * @param role 角色ID（1-学生，2-教师，3-管理员）
     * @return 操作结果
     */
    @Override
    @Transactional
    public Result updateUserRole(Integer userId, Integer role) {
        try {
            log.info("修改用户角色，用户ID：{}，新角色：{}", userId, role);
            
            // 参数校验
            if (userId == null || userId <= 0) {
                return Result.error("用户ID无效");
            }
            
            if (role == null || (role != SystemConstants.ROLE_STUDENT && 
                                role != SystemConstants.ROLE_TEACHER && 
                                role != SystemConstants.ROLE_ADMIN)) {
                return Result.error("角色参数无效，请使用有效的角色ID");
            }
            
            // 查询用户是否存在
            Users user = this.getById(userId);
            if (user == null) {
                return Result.error("用户不存在，无法修改角色");
            }
            
            // 检查角色是否发生变化
            if (user.getRole() != null && user.getRole().equals(role)) {
                return Result.success("用户角色未发生变化", user.getRole());
            }
            
            // 更新用户角色
            LambdaUpdateWrapper<Users> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Users::getId, userId)
                        .set(Users::getRole, role)
                        .set(Users::getUpdatedAt, new Date());
            
            boolean updateResult = this.update(updateWrapper);
            if (!updateResult) {
                return Result.error("修改用户角色失败，请稍后重试");
            }
            
            // 返回成功结果
            Map<String, Object> resultData = new HashMap<>();
            resultData.put("userId", userId);
            resultData.put("role", role);
            resultData.put("updateTime", new Date());
            
            log.info("用户角色修改成功，用户ID：{}，新角色：{}", userId, role);
            return Result.success("用户角色修改成功", resultData);
        } catch (Exception e) {
            log.error("修改用户角色异常：", e);
            return Result.error("修改用户角色发生异常：" + e.getMessage());
        }
    }

    @Override
    public Result checkUserPassword(Long userId) {
        try {
            // 参数校验
            if (userId == null) {
                return Result.error("用户ID不能为空");
            }

            // 查询用户信息
            Users user = this.getById(userId);
            if (user == null) {
                return Result.error("用户不存在");
            }

            // 检查用户是否已设置密码
            boolean hasPassword = StrUtil.isNotBlank(user.getPassword());

            // 构建返回数据
            Map<String, Object> resultData = new HashMap<>();
            resultData.put("userId", userId);
            resultData.put("hasPassword", hasPassword);

            log.info("检查用户密码状态成功，用户ID：{}，是否已设置密码：{}", userId, hasPassword);
            return Result.success("检查密码状态成功", resultData);

        } catch (Exception e) {
            log.error("检查用户密码状态异常：", e);
            return Result.error("检查密码状态发生异常：" + e.getMessage());
        }
    }

    @Override
    public Result updatePassword(UpdatePasswordRequest updatePasswordRequest) {
        try {
            // 1. 参数校验
            if (updatePasswordRequest == null) {
                return Result.error("修改密码请求不能为空");
            }

            // 判断是基于旧密码修改还是基于验证码修改
            if (updatePasswordRequest.getUserId() != null &&
                StrUtil.isNotBlank(updatePasswordRequest.getOldPassword()) &&
                StrUtil.isNotBlank(updatePasswordRequest.getNewPassword())) {
                // 基于旧密码验证的修改方式
                return updatePasswordByOldPassword(updatePasswordRequest);
            } else if (StrUtil.isNotBlank(updatePasswordRequest.getPhone()) &&
                       StrUtil.isNotBlank(updatePasswordRequest.getCode()) &&
                       StrUtil.isNotBlank(updatePasswordRequest.getPassword())) {
                // 基于验证码的修改方式（兼容旧版本）
                return updatePasswordByCode(updatePasswordRequest);
            } else {
                return Result.error("请求参数不完整，请提供完整的修改密码信息");
            }

        } catch (Exception e) {
            log.error("修改用户密码异常：", e);
            return Result.error("修改密码发生异常：" + e.getMessage());
        }
    }

    /**
     * 基于旧密码验证的密码修改
     */
    private Result updatePasswordByOldPassword(UpdatePasswordRequest updatePasswordRequest) {
        Long userId = updatePasswordRequest.getUserId();
        String oldPassword = updatePasswordRequest.getOldPassword();
        String newPassword = updatePasswordRequest.getNewPassword();

        // 1. 参数校验
        if (userId == null) {
            return Result.error("用户ID不能为空");
        }
        if (StrUtil.isBlank(oldPassword)) {
            return Result.error("旧密码不能为空");
        }
        if (StrUtil.isBlank(newPassword)) {
            return Result.error("新密码不能为空");
        }
        if (newPassword.length() < 6) {
            return Result.error("新密码长度不能少于6位");
        }
        if (oldPassword.equals(newPassword)) {
            return Result.error("新密码不能与旧密码相同");
        }

        // 2. 查询用户
        Users user = this.getById(userId);
        if (user == null) {
            return Result.error("用户不存在");
        }

        // 3. 验证旧密码
        if (StrUtil.isBlank(user.getPassword())) {
            return Result.error("该用户未设置密码，请使用验证码方式设置密码");
        }

        String encryptedOldPassword = DigestUtils.md5DigestAsHex((oldPassword + PASSWORD_SALT).getBytes());
        if (!encryptedOldPassword.equals(user.getPassword())) {
            return Result.error("旧密码错误");
        }

        // 4. 加密新密码
        String encryptedNewPassword = DigestUtils.md5DigestAsHex((newPassword + PASSWORD_SALT).getBytes());

        // 5. 更新用户密码
        user.setPassword(encryptedNewPassword);
        user.setUpdatedAt(new Date());

        boolean updateResult = this.updateById(user);
        if (!updateResult) {
            return Result.error("密码修改失败");
        }

        // 6. 构建返回数据
        Map<String, Object> resultData = new HashMap<>();
        resultData.put("userId", userId);
        resultData.put("phone", user.getPhone());
        resultData.put("updateTime", new Date());

        log.info("用户密码修改成功（旧密码验证），用户ID：{}，手机号：{}", userId, user.getPhone());
        return Result.success("密码修改成功", resultData);
    }

    /**
     * 基于验证码的密码修改（兼容旧版本）
     */
    private Result updatePasswordByCode(UpdatePasswordRequest updatePasswordRequest) {
        String phone = updatePasswordRequest.getPhone();
        String code = updatePasswordRequest.getCode();
        String password = updatePasswordRequest.getPassword();

        // 校验手机号
        if (StrUtil.isBlank(phone)) {
            return Result.error("手机号不能为空");
        }
        if (!validatePhoneFormat(phone)) {
            return Result.error("手机号格式不正确，请输入11位有效手机号");
        }

        // 校验验证码
        if (StrUtil.isBlank(code)) {
            return Result.error("验证码不能为空");
        }

        // 校验新密码
        if (StrUtil.isBlank(password)) {
            return Result.error("新密码不能为空");
        }
        if (password.length() < 6) {
            return Result.error("密码长度不能少于6位");
        }

        // 验证码校验
        Result codeValidationResult = validateVerificationCode(phone, code);
        if (codeValidationResult != null) {
            return codeValidationResult;
        }

        // 查询用户
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getPhone, phone);
        Users user = this.getOne(queryWrapper);

        if (user == null) {
            return Result.error("用户不存在");
        }

        // 加密新密码
        String encryptedPassword = DigestUtils.md5DigestAsHex((password + PASSWORD_SALT).getBytes());

        // 更新用户密码
        user.setPassword(encryptedPassword);
        user.setUpdatedAt(new Date());

        boolean updateResult = this.updateById(user);
        if (!updateResult) {
            return Result.error("密码修改失败");
        }

        // 构建返回数据
        Map<String, Object> resultData = new HashMap<>();
        resultData.put("userId", user.getId());
        resultData.put("phone", phone);
        resultData.put("updateTime", new Date());

        log.info("用户密码修改成功（验证码验证），用户ID：{}，手机号：{}", user.getId(), phone);
        return Result.success("密码修改成功", resultData);
    }
}
